package com.infoland.common.fastdfs;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;

import org.apache.commons.io.IOUtils;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.FileInfo;
import org.csource.fastdfs.ServerInfo;
import org.csource.fastdfs.StorageClient;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;

import com.jfinal.kit.LogKit;
import com.jfinal.kit.StrKit;

/**
 * fastdfs中的update,delete,upload,download方法
 * 
 * @author zpy 2015-12-9
 */
public class FileManager implements FileManagerConfig {
	private static final long serialVersionUID = 1L;

	private static TrackerClient trackerClient;
	private static TrackerServer trackerServer;
	private static StorageServer storageServer;
	private static StorageClient storageClient;

	static {
		try {
			String classPath = new File(FileManager.class.getResource("/").getFile()).getCanonicalPath();
			String fdfsClientConfigFilePath = classPath + File.separator + CLIENT_CONFIG_FILE;
			ClientGlobal.init(fdfsClientConfigFilePath);
			trackerClient = new TrackerClient();
			trackerServer = trackerClient.getConnection();
			storageClient = new StorageClient(trackerServer, storageServer);
			Socket socket = trackerServer.getSocket();
			org.csource.fastdfs.ProtoCommon.activeTest(socket);
		} catch (Exception e) {
			LogKit.error(e.getMessage());
		}
	}

	/**
	 * @param file文件对象
	 * @return
	 * @throws Exception
	 */
	public static String[] upload(String path, String fileName) {
		String[] uploadResults = null;
		if (StrKit.notNull(path) && StrKit.notNull(fileName)) {
			int ext = fileName.lastIndexOf(".");
			if (ext != -1) {
				String extStr = fileName.substring(ext + 1, fileName.length());
				File file = new File(path);
				FileInputStream fis;
				byte[] file_buff = null;
				try {
					fis = new FileInputStream(file);
					int len;
					if (fis != null) {
						len = fis.available();
						file_buff = new byte[len];
						fis.read(file_buff);
						FastDFSFile fd = new FastDFSFile(fileName, file_buff, extStr);
						NameValuePair[] meta_list = new NameValuePair[3];
						meta_list[0] = new NameValuePair("width", fd.getWidth());
						meta_list[1] = new NameValuePair("heigth", fd.getHeight());
						meta_list[2] = new NameValuePair("author", fd.getAuthor());
						uploadResults = storageClient.upload_file(fd.getContent(), fd.getExt(), meta_list);
						if (uploadResults == null) {
							LogKit.error("upload file fail, error code: " + storageClient.getErrorCode());
							extracted();
						}
						fis.close();
					}
				} catch (Exception e) {
					LogKit.error(e.getMessage());
				}
			
			}
		}
		return uploadResults;
	}

	private static void extracted() {
		throw new RuntimeException("upload file fail, error code: " + storageClient.getErrorCode());
	}

	/**
	 * @param groupName组名
	 * @param remoteFileName文件名
	 * @return 文件对象
	 */
	public static FileInfo getFile(String groupName, String remoteFileName) {
		if (StrKit.notNull(groupName) && StrKit.notNull(remoteFileName)) {
			try {
				return storageClient.get_file_info(groupName, remoteFileName);
			} catch (IOException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * @param groupName组名
	 * @param remoteFileName文件id
	 * @param clientPath保存路径
	 * @param fileName文件名
	 */
	public static void downLoadFile(String groupName, String remoteFileName, String clientPath, String fileName) {
		if (StrKit.notNull(groupName) && StrKit.notNull(remoteFileName) && StrKit.notNull(clientPath)
				&& StrKit.notNull(fileName)) {
			int ext = remoteFileName.lastIndexOf(".");
			if (ext != -1) {
				String extStr = remoteFileName.substring(ext, remoteFileName.length());
				try {
					byte[] b = storageClient.download_file(groupName, remoteFileName);
					IOUtils.write(b, new FileOutputStream(clientPath + fileName + extStr));
				} catch (IOException e) {
					LogKit.error("IO Exception: Get File from Fast DFS failed" + e);
				} catch (Exception e) {
					LogKit.error("Non IO Exception: Get File from Fast DFS failed" + e);
				}
			}
		}
	}

	/**
	 * @param groupName
	 *            组名
	 * @param remoteFileName
	 *            文件名
	 * @throws Exception
	 */
	public static Integer deleteFile(String groupName, String remoteFileName) throws Exception {
		return storageClient.delete_file(groupName, remoteFileName);
	}

	public static StorageServer[] getStoreStorages(String groupName) throws IOException {
		return trackerClient.getStoreStorages(trackerServer, groupName);
	}

	public static ServerInfo[] getFetchStorages(String groupName, String remoteFileName) throws IOException {
		return trackerClient.getFetchStorages(trackerServer, groupName, remoteFileName);
	}
}
